package com.leinao.model.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.leinao.category.dto.CategoryRelationDto;
import com.leinao.category.model.CategoryRelation;
import com.leinao.commons.Response;
import com.leinao.config.EnvironmentConfig;
import com.leinao.constant.*;
import com.leinao.job.dto.JobInfoDto;
import com.leinao.login.dto.LoginResultDto;
import com.leinao.model.dao.ModelMapper;
import com.leinao.model.dto.*;
import com.leinao.model.model.Model;
import com.leinao.model.model.ModelProJobRelation;
import com.leinao.model.service.ModelService;
import com.leinao.project.dto.ProjectDataSetDto;
import com.leinao.project.dto.PublicProjectListDto;
import com.leinao.team.dto.TeamMemberDto;
import com.leinao.util.compare.ObjectCompare;
import com.leinao.util.page.PageInfo;
import io.swagger.models.auth.In;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.print.attribute.standard.JobName;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: weiwei
 * @Date: 2019/6/3 20:41
 * @Description:
 * @Version 1.0
 */
@Service
public class ModelServiceImpl implements ModelService {

    private static Logger logger = LoggerFactory.getLogger(ModelServiceImpl.class);

    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private EnvironmentConfig env;

    /**
     * 本地联调测试https API
     */
//    static {
//        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
//            @Override
//            public boolean verify(String hostname, SSLSession session) {
//                return true;
//            }
//        });
//    }

    /**
      * @Description  "关注/取消关注模型
      * @param modelId
      * @param attentionFlag
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:54
      */
    @Override
    public Response<Void> attentionModel(Long modelId, Integer attentionFlag, LoginResultDto userInfo) {

        try {
            Model model = modelMapper.getModelById(modelId);

            if (null == model) {
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_IS_NOT_EXIST_ERROR.getSeq(),
                        ModelEnum.MODEL_IS_NOT_EXIST_ERROR.getDesc(), null);
            }

            if (null != model && userInfo.getUserId().equals(model.getUserId())) {
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.USER_ATTENTION_OWN_MODEL_ERROR.getSeq(),
                        ModelEnum.USER_ATTENTION_OWN_MODEL_ERROR.getDesc(), null);
            }

            //查询该数据集是否公开给用户
            Integer publicCount = modelMapper.getUserModelPublicStatus(modelId, userInfo.getUserId());
            if(publicCount == 0 && model.getType() == 0){
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_IS_NOT_PUBLIC.getSeq(),
                        ModelEnum.MODEL_IS_NOT_PUBLIC.getDesc(), null);
            }

            Integer count = modelMapper.getUserAttentionStatus(modelId, userInfo.getUserId());

            //attentionFlag = 0  取消关注
            if (attentionFlag.equals(Constant.MODEL_NO_ATTENTION)) {
                //并未关注该数据集
                if (count == 0) {
                    return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_NO_ATTENTION_BY_USER_ERROR.getSeq(),
                                    ModelEnum.MODEL_NO_ATTENTION_BY_USER_ERROR.getDesc(), null);
                }

                Integer delCount = modelMapper.deleteUserAttention(modelId, attentionFlag, userInfo.getUserId());
                if (delCount == Constant.UPDATE_COUNT) {
                    return Response.ok();
                } else {
                    return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_ATTENTION_RELATION_DELETE_ERROR.getSeq(),
                                    ModelEnum.MODEL_ATTENTION_RELATION_DELETE_ERROR.getDesc(), null);
                }
            }else {
                //attentionFlag = 1  加关注
                //已经关注该数据集
                if (count == 1) {
                    return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_IS_ATTENTION_BY_USER_ERROR.getSeq(),
                                    ModelEnum.MODEL_IS_ATTENTION_BY_USER_ERROR.getDesc(), null);
                }
                //需要判断数据库是否有记录
                Integer recordCount = modelMapper.selectRecord(modelId, userInfo.getUserId());
                Integer updateCount;

                if(recordCount == 0){
                    updateCount = modelMapper.insertUserAttention(modelId, attentionFlag, userInfo.getUserId());

                }else {
                    updateCount = modelMapper.updateUserAttention(modelId, attentionFlag, userInfo.getUserId());
                }

                if (updateCount == Constant.UPDATE_COUNT) {
                    return Response.ok();
                } else {
                    return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_ATTENTION_RELATION_INSERT_ERROR.getSeq(),
                                    ModelEnum.MODEL_ATTENTION_RELATION_INSERT_ERROR.getDesc(), null);
                }
            }

        } catch (Exception e) {
            logger.error("attentionModel Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.ATTENTION_MODEL_FAIL.getSeq(),
                                    ModelErrorEnum.ATTENTION_MODEL_FAIL.getDesc(),null);
        }
    }

    /**
      * @Description 删除模型
      * @param modelId
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:53
      */
    @Override
    public Response<Void> deleteModel(Long modelId, LoginResultDto userInfo) {

        try {
            Model model = modelMapper.getModelById(modelId);

            if (null == model) {
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_IS_NOT_EXIST_ERROR.getSeq(),
                                    ModelEnum.MODEL_IS_NOT_EXIST_ERROR.getDesc(), null);
            }

            if(null == model.getUserId()){
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.MODEL_IS_NO_CREATER.getSeq(),
                                    ModelEnum.MODEL_IS_NO_CREATER.getDesc(), null);
            }

            if(!userInfo.getUserId().equals(model.getUserId())){
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.USER_IS_NOT_CREATER.getSeq(),
                                    ModelEnum.USER_IS_NOT_CREATER.getDesc(), null);
            }

            Integer updateCount = modelMapper.deleteModel(modelId);

            if (updateCount == Constant.UPDATE_COUNT) {
                return Response.ok();
            } else {
                return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelEnum.DELETE_MODEL_ERROR.getSeq(),
                                         ModelEnum.DELETE_MODEL_ERROR.getDesc(), null);
            }
        } catch (Exception e) {
            logger.error("deleteModel Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.DELETE_MODEL_FAIL.getSeq(),
                                         ModelErrorEnum.DELETE_MODEL_FAIL.getDesc(),null);
        }
    }

    /**
      * @Description 获取用户是否关注模型
      * @param modelId
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:52
      */
    @Override
    public Response<ModelAttentionInfo> getUserAttentionStatus(Long modelId, LoginResultDto userInfo) {

        try {

            ModelAttentionInfo modelAttentionInfo = new ModelAttentionInfo();
            Integer count = modelMapper.getUserAttentionStatus(modelId, userInfo.getUserId());
            Integer attentionCount = modelMapper.getModelAttentionCount(modelId);
            modelAttentionInfo.setAttentionCount(attentionCount);

            if(count == 1){
                modelAttentionInfo.setAttentionFlag(true);
            }else {
                modelAttentionInfo.setAttentionFlag(false);
            }
            return Response.ok(modelAttentionInfo);

        } catch (Exception e) {
            logger.error("getUserAttentionStatus Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS,
                    ModelErrorEnum.GET_MODEL_ATTENTION_STATUS_ERROR.getSeq(), ModelErrorEnum.GET_MODEL_ATTENTION_STATUS_ERROR.getDesc(),null);
        }

    }

    /**
      * @Description  平台用户公开的模型列表(不包含自己创建的)
      * @param pageNumber
      * @param pageSize
      * @param categoryId
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:52
      */
    @Override
    public Response<PageInfo> getPublicModelsExceptOwn(Integer pageNumber, Integer pageSize, Long categoryId, LoginResultDto userInfo) {

        PageInfo pageInfo = null;
        PageHelper.startPage(pageNumber, pageSize);
        List<PaiModelDto> modelList = Lists.newArrayList();
        try {
            modelList = modelMapper.getPublicModelsExceptOwn(categoryId, userInfo.getUserId());

            //模型封面
            initModelCover(modelList);

            // 初始化公开项目分类信息
            initDatasetCategoryInfo(modelList, categoryId == null ? Constant.DATASET_LONG_TYPE_EMPTY : categoryId);

            pageInfo = new PageInfo(modelList);

        } catch (Exception e) {
            logger.error("getPublicModelsExceptOwn Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.GET_PUBLIC_MODEL_EXCEPT_OWN_LIST_ERROR.getSeq(),
                                ModelErrorEnum.GET_PUBLIC_MODEL_EXCEPT_OWN_LIST_ERROR.getDesc(),null);
        }
        return Response.ok(pageInfo);
    }

    /**
      * @Description 平台用户公开的模型列表
      * @param pageNumber
      * @param pageSize
      * @param categoryId
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:51
      */
    @Override
    public Response<PageInfo> getPublicModels(Integer pageNumber, Integer pageSize, Long categoryId, LoginResultDto userInfo) {

        PageInfo pageInfo = null;
        PageHelper.startPage(pageNumber, pageSize);
        List<PaiModelDto> modelList = Lists.newArrayList();
        try {
            modelList = modelMapper.getPublicModels(categoryId, userInfo.getUserId());

            // 初始化公开项目分类信息
            initDatasetCategoryInfo(modelList, categoryId == null ? Constant.DATASET_LONG_TYPE_EMPTY : categoryId);

            //模型封面
            initModelCover(modelList);

            pageInfo = new PageInfo(modelList);

        } catch (Exception e) {
            logger.error("getPublicModels Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.GET_PUBLIC_MODEL_LIST_ERROR.getSeq(),
                            ModelErrorEnum.GET_PUBLIC_MODEL_LIST_ERROR.getDesc(),null);
        }
        return Response.ok(pageInfo);
    }

    /**
      * @Description  关注模型列表
      * @param pageNumber
      * @param pageSize
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:57
      */
    @Override
    public Response<PageInfo> getAttentionModels(Integer pageNumber, Integer pageSize, LoginResultDto userInfo) {

        PageInfo pageInfo = null;
        PageHelper.startPage(pageNumber, pageSize);
        List<PaiModelDto> modelList = Lists.newArrayList();
        try {
            modelList = modelMapper.getAttentionModels(userInfo.getUserId());

            // 初始化公开项目分类信息
            initDatasetCategoryInfo(modelList, Constant.DATASET_LONG_TYPE_EMPTY);

            //模型封面
            initModelCover(modelList);

            pageInfo = new PageInfo(modelList);

        } catch (Exception e) {
            logger.error("getAttentionModels Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.GET_ATTENTION_MODEL_LIST_ERROR.getSeq(),
                         ModelErrorEnum.GET_ATTENTION_MODEL_LIST_ERROR.getDesc(),null);
        }
        return Response.ok(pageInfo);
    }

    /**
      * @Description  用户个人创建模型列表
      * @param pageNumber
      * @param pageSize
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:58
      */
    @Override
    public Response<PageInfo> getUserOwnModels(Integer pageNumber, Integer pageSize, LoginResultDto userInfo) {

        PageInfo pageInfo = null;
        PageHelper.startPage(pageNumber, pageSize);
        List<PaiModelDto> modelList = Lists.newArrayList();
        try {
            modelList = modelMapper.getUserOwnModels(userInfo.getUserId());

            // 初始化公开项目分类信息
            initDatasetCategoryInfo(modelList, Constant.DATASET_LONG_TYPE_EMPTY);

            //模型封面
            initModelCover(modelList);

            pageInfo = new PageInfo(modelList);

        } catch (Exception e) {
            logger.error("getUserOwnModels Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.GET_USER_OWN_MODEL_LIST_ERROR.getSeq(),
                    ModelErrorEnum.GET_USER_OWN_MODEL_LIST_ERROR.getDesc(),null);
        }
        return Response.ok(pageInfo);
    }

    /**
      * @Description  用户个人模型列表(创建+关注)
      * @param pageNumber
      * @param pageSize
      * @param userInfo
      * @return
      * @author:    weiwei
      * @Date:  2019/6/11 16:58
      */
    @Override
    public Response<PageInfo> getUserModels(Integer pageNumber, Integer pageSize, LoginResultDto userInfo) {


        PageInfo pageInfo = null;
        PageHelper.startPage(pageNumber, pageSize);
        List<PaiModelDto> modelList = Lists.newArrayList();
        try {
            modelList = modelMapper.getUserModels(userInfo.getUserId());

//            //模型封面
//            initModelCover(modelList);

//            // 初始化公开项目分类信息
//            initDatasetCategoryInfo(modelList, Constant.DATASET_LONG_TYPE_EMPTY);

            pageInfo = new PageInfo(modelList);

        } catch (Exception e) {
            logger.error("getUserModels Exception", e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.GET_USER_OWN_MODEL_LIST_ERROR.getSeq(),
                    ModelErrorEnum.GET_USER_OWN_MODEL_LIST_ERROR.getDesc(),null);
        }
        return Response.ok(pageInfo);
    }


    /**
     * @Description    获取数据集封面图片地址
     * @param modelList    模型列表
     * @return
     * @author:    weiwei
     * @Date:  2019/6/4 14:21
     */
    private void initModelCover(List<PaiModelDto> modelList) {
        if(CollectionUtils.isEmpty(modelList)) {
            return;
        }

        // 获取数据集封面图片地址
        List<Long> modelIds = modelList.stream().map(PaiModelDto::getId).collect(Collectors.toList());
        List<PaiModelDto> modelCoverUrlList = modelMapper.getModelCoverUrlList(modelIds);

        if(!CollectionUtils.isEmpty(modelCoverUrlList)) {
            modelList.forEach(model -> {
                modelCoverUrlList.forEach(modelCoverUrl -> {
                    if(model.getId().equals(modelCoverUrl.getId()) && StringUtils.isNotEmpty(modelCoverUrl.getCoverUrl())) {
                        model.setCoverUrl(modelCoverUrl.getCoverUrl());
                    }
                });
            });
        }
    }

    private void initDatasetCategoryInfo(List<PaiModelDto> modelList, Long categoryId) {
        if(CollectionUtils.isEmpty(modelList)) {
            return;
        }

        // 获取数据集对应的项目ID集合
        List<Long> modelIds = modelList.stream().map(PaiModelDto::getId).collect(Collectors.toList());
        List<CategoryRelationDto> categoryRelationList = modelMapper.getCategoryListByObjectIdListAndType(modelIds, CategoryRelationTypeEnum.MODEL.getType());
        if(CollectionUtils.isEmpty(categoryRelationList)) {
            return;
        }

        for(int i = 0; i < modelList.size(); i ++){
            for(int j = 0; j < categoryRelationList.size(); j ++){
                if(modelList.get(i).getId().equals(categoryRelationList.get(j).getObjId())) {
                    if(categoryId.equals(categoryRelationList.get(j).getCategoryId())){
                        modelList.get(i).getCategoryList().add(0,categoryRelationList.get(j));
                    }else {
                        modelList.get(i).getCategoryList().add(categoryRelationList.get(j));
                    }
                }
            }
        }
    }
    /**
      * 功能描述: 创建模型入库
      * @param userId
      * @param modelName
      * @param modelIntroduction
      * @param projectId
      * @param jobId
      * @Return:com.leinao.commons.Response<java.lang.Void>
      * @Author:HuoPengfei
      * @Date:2019/6/5 15:25
      */
    @Override
    public Response<Void> createModel(String userId,String modelName, String modelIntroduction,Long projectId, Long jobId,String language,String framework,Boolean localUpload) {
        Long modelForUserId = modelMapper.getModelForUserId(modelName, userId);
        if(modelForUserId!=null){
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.MODEL_NAME_IS_ALREADY.getSeq(), ModelErrorEnum.MODEL_NAME_IS_ALREADY.getDesc(), null);
        }
        Model lanAndFra = modelMapper.getLanAndFra(projectId);
        Model model = new Model();
        model.setModelName(modelName);
        model.setModelIntroduction(modelIntroduction);
        model.setUserId(userId);
        if(localUpload){
            model.setLanguage(language);
            model.setFramework(framework);
        }else {
            model.setLanguage(lanAndFra.getLanguage());
            model.setFramework(lanAndFra.getFramework());
        }
        model.setCreateTime(System.currentTimeMillis());
        model.setUpdateTime(System.currentTimeMillis());
        modelMapper.saveModelDetail(model);
        ModelProJobRelation modelProJobRelation = new ModelProJobRelation();
        modelProJobRelation.setModelId(model.getId());
        modelProJobRelation.setProjectId(projectId);
        modelProJobRelation.setJobId(jobId);
        modelProJobRelation.setUserId(userId);
        modelProJobRelation.setCreateTime(System.currentTimeMillis());
        modelProJobRelation.setUpdateTime(System.currentTimeMillis());
        modelMapper.saveModelRelation(modelProJobRelation);
        return Response.ok();
    }
    /**
      * 功能描述: 获取我创建的和我克隆的项目信息
      * @param userId
      * @Return:com.leinao.commons.Response<java.util.List<com.leinao.model.dto.ProjectDto>>
      * @Author:HuoPengfei
      * @Date:2019/6/5 15:25
      */
    @Override
    public Response<List<ProjectDto>> getProName(String userId,String projectName) {
        List<ProjectDto> proList = modelMapper.getProName(userId,projectName);
        return Response.ok(proList);
    }
    /**
      * 功能描述: 获取任务信息
      * @param projectId
      * @Return:com.leinao.commons.Response<java.util.List<com.leinao.model.dto.JobDto>>
      * @Author:HuoPengfei
      * @Date:2019/6/5 15:25
      */
    @Override
    public Response<List<JobInfoDto>> getJobName(Long projectId,String jobName,LoginResultDto userInfo) {
        List<JobDto> jobList = modelMapper.getJobName(projectId, jobName);
        Response<List<JobInfoDto>> succeeded = getProjectJobInfo("SUCCEEDED", userInfo.getToken(), jobList);
        return succeeded;
    }
    /**
      * 功能描述: 项目列表
      * @param modelId
      * @param currentPage
      * @param pageSize
      * @Return:com.leinao.commons.Response<com.leinao.util.page.PageInfo>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:19
      */
    @Override
    public Response<PageInfo> getProjectByModelId(Long modelId,Integer type,String userId,Integer currentPage,Integer pageSize) {
        if(type==0) {
            Long userModelRela = modelMapper.getUserModelRela(modelId, userId);
            if(userModelRela==null){
                return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.YOU_DO_NOT_HAVA_PERMISSION_OF_THIS_MODEL.getSeq(), ModelErrorEnum.YOU_DO_NOT_HAVA_PERMISSION_OF_THIS_MODEL.getDesc(), null);
            }
        }
        PageHelper.startPage(currentPage, pageSize);
        List<ProjectDto> projectByModelId = modelMapper.getProjectByModelId(modelId);
        List<CategoryRelationDto> projectTag = modelMapper.getProjectTag(modelId);
        projectByModelId.forEach(project->
            projectTag.forEach(tag->{
                if(project.getId().equals(tag.getObjId())){
                    project.getCategoryList().add(tag);
                }
            })
        );
        PageInfo<ProjectDto> pageInfo = new PageInfo<>(projectByModelId==null? Collections.emptyList(): projectByModelId);
        return Response.ok(pageInfo);
    }
    /**
      * 功能描述: 公开模型详情
      * @param modelId
      * @Return:com.leinao.commons.Response<com.leinao.model.model.Model>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:19
      */
    @Override
    public Response<Model> getModelDetail(Long modelId,Integer type,String userId) {
        if(type==0) {
            Long userModelRela = modelMapper.getUserModelRela(modelId, userId);
            if(userModelRela==null){
                return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ModelErrorEnum.YOU_DO_NOT_HAVA_PERMISSION_OF_THIS_MODEL.getSeq(), ModelErrorEnum.YOU_DO_NOT_HAVA_PERMISSION_OF_THIS_MODEL.getDesc(), null);
            }
        }
        Model modelDetail = modelMapper.getModelDetail(modelId);
        List<Long> openPersonal = modelMapper.getOpenPersonal(modelId);
        if (openPersonal.size() > 0) {
            modelDetail.setPersonal(true);
        } else {
            modelDetail.setPersonal(false);
        }
        return Response.ok(modelDetail);
    }
    /**
      * 功能描述: 修改简介
      * @param id
      * @param userId
      * @param introduction
      * @Return:com.leinao.commons.Response<java.lang.Integer>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:19
      */
    @Override
    public Response<Integer> updateModelIntro(Long id, String userId,String introduction) {
        Integer integer = modelMapper.updateModelIntro(id, userId,introduction);
        return Response.ok(integer);
    }
    /**
      * 功能描述: 我的模型详情
      * @param modelId
      * @param userId
      * @Return:com.leinao.commons.Response<com.leinao.model.model.Model>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:19
      */
    @Override
    public Response<Model> getModelDetailForCreate(Long modelId,String userId) {
        Model modelDetail = modelMapper.getModelDetailForCreate(modelId,userId);
        List<Long> openPersonal = modelMapper.getOpenPersonal(modelId);
        if(modelDetail!=null) {
            if (openPersonal.size() > 0) {
                modelDetail.setPersonal(true);
            } else {
                modelDetail.setPersonal(false);
            }
        }
        return Response.ok(modelDetail);
    }
    /**
      * 功能描述: 项目分页
      * @param modelId
      * @param userId
      * @param currentPage
      * @param pageSize
      * @Return:com.leinao.commons.Response<com.leinao.util.page.PageInfo>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:19
      */
    @Override
    public Response<PageInfo> getProjectByModelIdForCreate(Long modelId,String userId,Integer currentPage,Integer pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<ProjectDto> projectByModelId = modelMapper.getProjectByModelIdForCreate(modelId,userId);
        PageInfo<ProjectDto> pageInfo = new PageInfo<>(projectByModelId==null? Collections.emptyList(): projectByModelId);
        return Response.ok(pageInfo);
    }
    /**
      * 功能描述: 公开模型
      * @param userId
      * @param tagList
      * @param userList
      * @param modelId
      * @param modelCoverId
      * @param openAll
      * @Return:com.leinao.commons.Response<java.lang.Integer>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:20
      */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public Response<Integer> openModel(String userId, Long[] tagList, String[] userList, Long modelId, Long modelCoverId, Boolean openAll) {
        modelMapper.deleteObjCategroyRe(modelId);
        for (int i = 0; i < tagList.length; i++) {
            CategoryRelation categoryRelation = new CategoryRelation();
            categoryRelation.setObjId(modelId);
            categoryRelation.setCategoryId(tagList[i]);
            categoryRelation.setCreateTime(System.currentTimeMillis());
            categoryRelation.setUpdateTime(System.currentTimeMillis());
            categoryRelation.setUserId(userId);
            modelMapper.saveTagModelRelation(categoryRelation);
        }
        if(openAll){
            modelMapper.openModelToAll(modelId,userId);
        }else {
            if(userList!=null){
                for (int i = 0; i < userList.length; i++) {
                    if(userList[i].equals(userId)){
                        throw new RuntimeException(ModelErrorEnum.YOU_CAN_NOT_OPEN_TO_YOURSELF.getDesc());
                    }
                    modelMapper.savePersonalRelation(userList[i],modelId);
                }
            }
        }
        Long fileReId = modelMapper.getFileReIdByModel(modelId);
        if(modelCoverId!=null&&fileReId!=null){
            Integer integer = modelMapper.deleteFileRelation(fileReId);
        }
        Long fileReId1 = modelMapper.getFileReIdByModel(modelId);
        if(modelCoverId!=null&&fileReId1==null){
            ModelCoverDto modelCoverDto = new ModelCoverDto();
            modelCoverDto.setType(3);
            modelCoverDto.setFileId(modelCoverId);
            modelCoverDto.setObjId(modelId);
            modelCoverDto.setCreateTime(System.currentTimeMillis());
            modelCoverDto.setUpdateTime(System.currentTimeMillis());
            modelMapper.saveModelCover(modelCoverDto);
        }
        return Response.ok(null);
    }
    /**
      * 功能描述: 回显公开人
      * @param modelId
      * @Return:com.leinao.commons.Response<java.util.List<com.leinao.team.dto.TeamMemberDto>>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:20
      */
    @Override
    public Response<List<TeamMemberDto>> getPersonalRelation(Long modelId) {
        List<TeamMemberDto> personalRelation = modelMapper.getPersonalRelation(modelId);
        return Response.ok(personalRelation);
    }
    /**
      * 功能描述: 取消公开
      * @param id
      * @param userId
      * @Return:com.leinao.commons.Response<java.lang.Integer>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:20
      */
    @Override
    public Response<Integer> deletePersonalRelation(Long id, String userId) {
        Integer integer = modelMapper.deletePersonalRelation(id, userId);
        modelMapper.updateUserModelZero(id,userId);
        List<Long> projectId = modelMapper.getProjectId(id, userId);
        if(!projectId.isEmpty()){
            modelMapper.deleteProjectModelRelationForProjectId(id, projectId);
        }
        return Response.ok(integer);
    }
    /**
      * 功能描述: 回显标签
      * @param modelId
      * @Return:com.leinao.commons.Response<java.util.List<com.leinao.model.dto.ModelCategoryDto>>
      * @Author:HuoPengfei
      * @Date:2019/6/13 18:20
      */
    @Override
    public Response<List<ModelCategoryDto>> getOpenCategory(Long modelId) {
        List<ModelCategoryDto> openCategory = modelMapper.getOpenCategory(modelId);
        return Response.ok(openCategory);
    }



    @Override
    public Response<List<Model>> getModelType(String modelIds) {
        List<Long> list = Lists.newArrayList();
        if(StringUtils.isNotBlank(modelIds)) {
            String[] modelIdArr = modelIds.split(",");
            for(String modelId : modelIdArr) {
                list.add(Long.parseLong(modelId));
            }
        }
        List<Model> modelsTypes = modelMapper.getModelsTypes(list);
        return Response.ok(modelsTypes);
    }

    //SUCCEEDED
    public Response<List<JobInfoDto>> getProjectJobInfo(String taskStatus, String token, List<JobDto> jobList) {
        try {
            if(org.apache.commons.collections.CollectionUtils.isNotEmpty(jobList)) {
                StringBuilder sb = new StringBuilder(env.getRestServerUrl() + Constant.REST_SERVER_BATCH_QUERY_JOB_API);
                for(JobDto ppj : jobList) {
                    logger.debug("jobName: {}", ppj.getJobName());
                    sb.append(ppj.getJobName()).append(",");
                }
                String batchQueryJobInfoUrl = sb.toString();
                logger.debug("batchQueryJobInfoUrl: {}", batchQueryJobInfoUrl);
                List<JobInfoDto> jobInfoList = batchQueryJobInfo(batchQueryJobInfoUrl, token);
                for(JobDto projectJob : jobList) {
                    for(JobInfoDto jobInfo : jobInfoList) {
                        if(projectJob.getJobName().equals(jobInfo.getJobName())) {
                            jobInfo.setCodeNo(projectJob.getCodeNo());
                            jobInfo.setId(projectJob.getId());
                        }
                    }
                }
                ObjectCompare<JobInfoDto> oc = new ObjectCompare<JobInfoDto>(JobInfoDto.class.getDeclaredField("createdTime"), ObjectCompare.DIRECT_DESC, ObjectCompare.SORT_TYPE_COMPARABLE_VALUE);
                if(StringUtils.isNotEmpty(taskStatus)){
                    jobInfoList.removeIf(projectJobView -> {
                        System.out.println(projectJobView.getState());
                        ProjectJobStateEnum jobStateParamEnum = ProjectJobStateEnum.enumOf(taskStatus);
                        ProjectJobStateEnum jobStateResultEnum = ProjectJobStateEnum.enumOf(projectJobView.getState());
                        // 状态为STOPPED和STOPPING合并为STOPPED分类
                        if(ProjectJobStateEnum.STOPPED == jobStateParamEnum && ProjectJobStateEnum.STOPPING == jobStateResultEnum) {
                            return false;
                        }
                        return !taskStatus.equalsIgnoreCase(projectJobView.getState());
                    });
                }
                Collections.sort(jobInfoList, oc);
                return Response.ok(jobInfoList);
            }else{
                return Response.ok(new ArrayList<>());
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ProjectEnum.GET_PROJECT_DETAIL_ERROR.getSeq(),ProjectEnum.GET_PROJECT_DETAIL_ERROR.getDesc(),null);
        }
    }
    /**
     * @description 批量查询任务信息
     * @param batchQueryJobInfoUrl
     * @param token
     * @return
     * @author wangshoufa
     * @date 2018年11月28日
     */
    private List<JobInfoDto> batchQueryJobInfo(String batchQueryJobInfoUrl, String token){
        List<JobInfoDto> list = Lists.newArrayList();
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("Authorization", "Bearer " + token);
        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        String body = "";
        try {
            ResponseEntity<String> responseEntity = restTemplate.exchange(batchQueryJobInfoUrl,
                    HttpMethod.GET, formEntity, String.class);
            logger.info("request batchQueryJobInfo return: {}", JSON.toJSON(responseEntity));
            if (responseEntity.getStatusCodeValue() == 200) {
                logger.info("batchQueryJobInfo success");
                body = responseEntity.getBody();
                JSONArray parseArray = JSON.parseArray(body);
                logger.info("batchQueryJobInfo resp: {}", parseArray);
                for(int i = 0; i < parseArray.size(); i++) {
                    JobInfoDto jobInfo = new JobInfoDto();
                    JSONObject jsonObject = (JSONObject) parseArray.get(i);
                    String jobName = jsonObject.getString("name");
                    String userId = jsonObject.getString("userId");
                    String state = jsonObject.getString("state");
                    String executionType = jsonObject.getString("executionType");
                    Integer retries = jsonObject.getInteger("retries");
                    //获取任务中容器最早的启动时间，且设置为任务创建时间
                    JSONObject taskRoleDetailInfo = (JSONObject)JSON.parseObject(jsonObject.toString()).get("taskRoleDetailInfo");
                    Long createdTime=0L;
                    Long completedTime=0L;
                    //用时
                    Long timeConsuming=0L;
                    if(!taskRoleDetailInfo.isEmpty()){
                        Set<String> keys = taskRoleDetailInfo.keySet();
                        List<Long> containerLaunchedTimestampList=new ArrayList<Long>();
                        List<Long> containerCompletedTimestampList=new ArrayList<Long>();
                        Iterator iterator = keys.iterator();
                        while(iterator.hasNext()){
                            String key = (String) iterator.next();
                            Object taskRole =taskRoleDetailInfo.get(key);
                            Object taskStatuses = JSON.parseObject(taskRole.toString()).get("taskStatuses");
                            JSONArray taskStatusArray = JSON.parseObject(taskStatuses.toString()).getJSONArray("taskStatusArray");

                            for (int j = 0; j < taskStatusArray.size(); j++) {
                                JSONObject obj = (JSONObject) taskStatusArray.get(j);
                                Long containerLaunchedTimestamp = obj.getLong("containerLaunchedTimestamp");
                                Long containerCompletedTimestamp = obj.getLong("containerCompletedTimestamp");
                                if(containerLaunchedTimestamp==null){
                                    containerLaunchedTimestamp=0L;
                                }
                                if(containerCompletedTimestamp==null){
                                    containerCompletedTimestamp=0L;
                                }
                                containerLaunchedTimestampList.add(containerLaunchedTimestamp);
                                containerCompletedTimestampList.add(containerCompletedTimestamp);
                            }
                        }

                        if(containerLaunchedTimestampList.size()>0){
                            createdTime=Collections.min(containerLaunchedTimestampList);
                        }
                        if(containerCompletedTimestampList.size()>0){
                            completedTime=Collections.max(containerCompletedTimestampList);
                        }
                    }
                    if(Constant.JOB_STATUS_NOT_FOUND.equals(state)){
                        createdTime=0L;
                        completedTime=0L;
                        timeConsuming=0L;
                    }
                    if(Constant.JOB_STATUS_WAITING.equals(state)){
                        createdTime=0L;
                        completedTime=0L;
                        timeConsuming=0L;
                    }
                    if(Constant.JOB_STATUS_RUNNING.equals(state)){
                        timeConsuming=(long)Math.ceil(Math.max(0,(System.currentTimeMillis()-createdTime))/1000);
                    }
                    if(Constant.JOB_STATUS_SUCCEEDED.equals(state)){
                        timeConsuming=(long)Math.ceil(Math.max(0,(completedTime-createdTime))/1000);
                    }
                    if(Constant.JOB_STATUS_FAILED.equals(state)&&createdTime>0&&completedTime>0){
                        timeConsuming=(long)Math.ceil(Math.max(0,(completedTime-createdTime))/1000);
                    }
                    if(Constant.JOB_STATUS_STOPPED.equals(state)&&createdTime>0&&completedTime>0){
                        timeConsuming=(long)Math.ceil(Math.max(0,(completedTime-createdTime))/1000);
                    }
                    jobInfo.setTimeConsuming(timeConsuming);
                    jobInfo.setJobName(jobName);
                    jobInfo.setUserId(userId);
                    jobInfo.setState(state);
                    jobInfo.setExecutionType(executionType);
                    jobInfo.setRetries(retries);
                    jobInfo.setCompletedTime(completedTime);
                    jobInfo.setCreatedTime(createdTime);
                    list.add(jobInfo);
                }

                return list;
            }
            return list;
        } catch (Exception e) {
            logger.error("batchQueryJobInfo error");
            logger.error(e.getMessage(), e);
            return list;
        }
    }
}
